package com.it13.utils.httputil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.StatusLine;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

import com.it13.utils.dateutil.DateUtil;
import com.it13.utils.dateutil.DateUtil.DateFormatType;
import com.it13.utils.strutil.StrUtil;

/**
 * http请求工具类
 * @author yzChen
 * @date 2013-7-25 下午9:32:51
 * <pre>
 *	desc:
 * </pre>
 */
public class ReqUtil {
	// 请求客户端实例
	private HttpClient client;
	// 请求对象
	private HttpMethod method;
	// 返回状态
	private StatusLine statusline;
	
	/**
	 * 初始化
	 */
	public ReqUtil() {
		this.client = new HttpClient();
	}
	
	/**
	 * 匹配对应的method对象
	 * @param requestType
	 * @param url
	 * @param body
	 * @throws HttpException    
	 * @author yzChen  cyzshenzhen@163.com
	 * @date 2013-10-14 下午11:50:25
	 */
	@SuppressWarnings("deprecation")
	private void getMethodByType(RequestType requestType, String url, String body) throws HttpException {
		// 获取请求方式
		if (requestType == RequestType.GET) {
			this.method = new GetMethod(url);
		} else if (requestType == RequestType.POST) {
			PostMethod post = new PostMethod(url);
			// 设置参数
			if(StrUtil.isNotEmpty(body)) {
				post.setRequestBody(body);
				post.getParams().setContentCharset("UTF-8");
			}
			this.method = post;
		} else {	// 请求方式异常
			throw new HttpException("请求方式错误");
		}
	}

	/**
	 * 正则获取字符编码。默认返回utf-8
	 * @param content
	 * @return
	 */
	private String getCharSet(final String content) {
		String charset = "utf-8";
		String regex = ".*charset=(.*\"{1})";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(content);
		if (matcher.find()) {
			String tempstr = matcher.group(1);
			charset = tempstr.substring(0, tempstr.length() - 1);
		}
		return charset;
	}
	
	/**
	 * http请求，method=get方式
	 * @param url	
	 * 		请求地址
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */
	public RespModel httpRequestGet(String url, String body) throws HttpException, IOException {
		return httpRequest(RequestType.GET, url, body);
	}
	
	/**
	 * http请求，method=post方式
	 * @param url	
	 * 		请求地址
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */
	public RespModel httpRequestPost(String url, String body) throws HttpException, IOException {
		return httpRequest(RequestType.POST, url, body);
	}
	
	/**
	 * http请求
	 * @param requestType	
	 * 		请求方式
	 * @param url	
	 * 		请求地址
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */
	public RespModel httpRequest(RequestType requestType, String url, String body) throws HttpException, IOException {
		// 获取请求对象
		getMethodByType(requestType, url, body);
		// 设置参数
		// 请求操作
		this.client.executeMethod(this.method);
		// 获取返回内容
		this.statusline = this.method.getStatusLine();
		// 处理结果
		byte[] bytes = this.method.getResponseBody();
		String content = new String(bytes, getCharSet(this.method.getResponseBodyAsString()));
		// 释放连接
		this.method.releaseConnection();
		// 返回
		return new RespModel(this.statusline, content);
	}
	
	/**
	 * 文件下载
	 * @param url	
	 * 		需要下载的文件地址
	 * @param filepath	
	 * 		下载保存地址
	 * @return
	 * @throws IOException
	 */
	public File httpDownloadGet(String url, String filepath) throws IOException {
		return httpDownload(RequestType.GET, url, filepath);
	}
	
	/**
	 * 文件下载
	 * @param url	
	 * 		需要下载的文件地址
	 * @param filepath	
	 * 		下载保存地址
	 * @return
	 * @throws IOException
	 */
	public File httpDownloadPost(String url, String filepath) throws IOException {
		return httpDownload(RequestType.POST, url, filepath);
	}
	
	/**
	 * 文件下载
	 * @param requestType	
	 * 		请求类型
	 * @param url	
	 * 		需要下载的文件地址
	 * @param filepath	
	 * 		下载保存地址
	 * @return
	 * @throws IOException
	 */
	public File httpDownload(RequestType requestType, String url, String filepath) throws IOException {
		// 获取请求对象
		getMethodByType(requestType, url, null);
		// 请求操作
		this.client.executeMethod(this.method);
		// 保存文件对象
		String path = StrUtil.appendSbf(filepath, DateUtil.date2Str(DateFormatType.SLASH), "/");
		File dirs = new File(path);
		dirs.mkdirs();
		File storeFile = new File(StrUtil.appendSbf(path, UUID.randomUUID(), StrUtil.getSuffix(url)));
		// 下载文件
		FileOutputStream output = new FileOutputStream(storeFile);
		// 保存文件
		output.write(this.method.getResponseBody());
		// 释放资源
		output.close();
		// 返回
		return storeFile;
	}
	
	/**
	 * 请求类型
	 * @author yzChen
	 * @date 2013-7-26 下午12:53:57
	 * <pre>
	 *	desc:
	 * </pre>
	 */
	enum RequestType {
		GET, POST
	}
}
